package com.ajun.es.doc;

import cn.hutool.core.collection.CollUtil;
import com.ajun.common.ESConstants;
import com.ajun.common.util.EsClientFactory;
import com.ajun.entity.User;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.platform.commons.annotation.Testable;

import java.io.IOException;

/**
 * ES Doc Tutorial
 *
 * @author AJun
 * @date 2021-07-20
 */
@Testable
@Slf4j
public class DocTutorial {

    RestHighLevelClient client;
    final String USER_INDEX = ESConstants.USER_INDEX;

    @BeforeEach
    void init() {
        client = EsClientFactory.esClient();
    }

    @AfterEach
    void destroy() {
        EsClientFactory.close();
    }

    /**
     * 插入数据
     */
    @Test
    void testInsertDoc() throws IOException {
        // 准备数据
        User user = User.builder().name("小明").sex("男性").age(18).build();
        String userJson = JSON.toJSONString(user);

        // 插入数据到文档,起一个唯一 id
        IndexRequest request = new IndexRequest()
            .index(USER_INDEX)
            .id("1001")
            .source(userJson, XContentType.JSON);
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        log.debug("响应信息: {}", response);
    }

    /**
     * 修改数据
     */
    @Test
    void testUpdateDoc() throws IOException {
        UpdateRequest updateRequest = new UpdateRequest()
            .index(USER_INDEX)
            .id("1001")
            .doc(XContentType.JSON, "sex", "女性");
        UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
        log.debug("响应信息: {}", updateResponse);
    }

    /**
     * 查询数据
     */
    @Test
    void testQueryDoc() throws IOException {
        GetRequest getRequest = new GetRequest()
            .index(USER_INDEX)
            .id("1001");
        GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
        log.debug("响应信息: {}", response);
        log.debug("响应信息: {}", response.getSourceAsString());
    }

    /**
     * 删除数据
     */
    @Test
    void testDeleteDoc() throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest()
            .index(USER_INDEX)
            .id("1001");
        DeleteResponse response = client.delete(deleteRequest, RequestOptions.DEFAULT);
        log.debug("响应信息: {}", response);
    }

    /**
     * 批量操作数据
     */
    @Test
    void testBulk() throws IOException {
        // 准备数据
        User user1 = User.builder().name("刘明").sex("男性").age(18).build();
        User user2 = User.builder().name("小李").sex("女性").age(19).build();
        User user3 = User.builder().name("小张").sex("男性").age(13).build();
        User user4 = User.builder().name("张三").sex("女性").age(14).build();
        User user5 = User.builder().name("李四").sex("男性").age(15).build();

        // 块请求,可以包装多个请求,实现批量操作数据
        BulkRequest bulkRequest = new BulkRequest().add(
            new IndexRequest().index(USER_INDEX).id("1001").source(JSON.toJSONString(user1), XContentType.JSON),
            new IndexRequest().index(USER_INDEX).id("1002").source(JSON.toJSONString(user2), XContentType.JSON),
            new IndexRequest().index(USER_INDEX).id("1003").source(JSON.toJSONString(user3), XContentType.JSON),
            new IndexRequest().index(USER_INDEX).id("1004").source(JSON.toJSONString(user4), XContentType.JSON),
            new IndexRequest().index(USER_INDEX).id("1005").source(JSON.toJSONString(user5), XContentType.JSON)
        );

        // 块响应
        BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        if (bulkResponse.hasFailures()) {
            log.error("失败响应信息: {}", bulkResponse.buildFailureMessage());
        }
        log.debug("耗时: {}", bulkResponse.getTook()); // 耗时
        log.debug("响应信息: {}", CollUtil.toList(bulkResponse.getItems()));
    }
}
